/* 
 * Copyright 2005 - 2009 Terracotta, Inc. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 
 * use this file except in compliance with the License. You may obtain a copy 
 * of the License at 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 *   
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 * License for the specific language governing permissions and limitations 
 * under the License.
 * 
 */

package com.baoxian.task.job.service;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.TriggerBuilder.newTrigger;

import java.io.*;
import java.util.Date;
import java.util.Properties;

import com.baoxian.task.job.datasource.JdbcUtil;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自动释放过期的任务
 *
 * @author Xiong Neng
 */
public class ReleaseTaskService {
    private static final Logger log = LoggerFactory.getLogger(ReleaseTaskService.class);

    /**
     * 自动释放过期的任务
     *
     * @param timeoutDays 任务过期天数
     * @param cron        定时任务表达式
     */
    public void run(int timeoutDays, int baojiaTimeoutDays, String cron) {
        try {
            log.info("------- 循环工作排程 jobs ----------------");
            JobDetail job = newJob(ReleaseTaskJob.class)
                    .withIdentity("job1", "group1")
                    .build();
            // 参数传递
            job.getJobDataMap().put("timeoutDays", timeoutDays);
            job.getJobDataMap().put("baojiaTimeoutDays", baojiaTimeoutDays);
            // 秒 分 时 日期 月份 星期
            CronTrigger trigger = newTrigger()
                    .withIdentity("trigger1", "group1")
                    .withSchedule(cronSchedule(cron))
                    .build();

            Date ft = sched.scheduleJob(job, trigger);
            log.info("JobKey：" + job.getKey() + " 第一次被触发执行的时间为: " + ft
                    + " | 循环执行表达式为: " + trigger.getCronExpression());

            log.info("------- 开始启动 Scheduler ----------------");
            sched.start();
            log.info("------- 完成启动 Scheduler -----------------");
        } catch (SchedulerException e) {
            log.error("---------定时任务处理失败-------", e);
        }
    }

    /**
     * 启动Scheduler
     *
     * @param configPath 配置文件路径
     */
    public void startScheduler(String configPath) {
        BufferedReader reader = null;
        try {
            log.info("------开始启动Scheduler------");
            JdbcUtil.initDataSource(configPath);
            initScheduler();
            Properties props = new Properties();
            reader = new BufferedReader(
                    new InputStreamReader(new FileInputStream(configPath + "taskjobConfig.properties")));
            props.load(reader);

            //历史任务
            int timeoutDays = Integer.parseInt(props.getProperty("com.baoxian.task.job.timeout.days"));
            //单方报价，多方报价过期天数
            int baojiaTimeoutDays = Integer.parseInt(props.getProperty("com.baoxian.baojia.task.job.timeout.days"));
            String cron = props.getProperty("com.baoxian.task.job.cron.expression");
            run(timeoutDays, baojiaTimeoutDays, cron);
            log.info("------结束启动Scheduler------");
        } catch (Exception e) {
            log.error("启动Scheduler出错", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error(e.getMessage(), e);
                }
            }

        }
    }

    /**
     * 停止定时任务服务
     */
    public void stopScheduler() {
        if (sched != null) {
            try {
                log.info("------- 开始关闭Scheduler ---------------------");
                sched.shutdown(true);
                log.info("------- 结束关闭Scheduler -----------------");
                SchedulerMetaData metaData = sched.getMetaData();
                log.info(" ---- 一共有 " + metaData.getNumberOfJobsExecuted() + " 个job被执行. ----");
            } catch (SchedulerException e) {
                log.error("---------停止定时候任务失败-------", e);
            }
        }
    }

    /**
     * 初始化Scheduler
     */
    private void initScheduler() {
        try {
            log.info("------- Scheduler 初始化定时任务开始-------------------");
            SchedulerFactory sf = new StdSchedulerFactory();
            sched = sf.getScheduler();
            log.info("------- Scheduler 初始化定时任务完成 --------");
        } catch (SchedulerException e) {
            log.error("----初始化Scheduler的时候出错----", e);
        }
    }

    private ReleaseTaskService() {
    }

    private static final ReleaseTaskService service = new ReleaseTaskService();

    public static ReleaseTaskService instantce() {
        return service;
    }

    private Scheduler sched;

}
